package com.csx.micrometer.sentinel.config;

import com.alibaba.csp.sentinel.metric.extension.MetricExtensionProvider;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.csx.micrometer.common.context.MonitorContext;
import com.csx.micrometer.sentinel.core.SentinelDegradeState;
import com.csx.micrometer.sentinel.core.SentinelMetricsExtension;
import com.csx.micrometer.sentinel.listener.SentinelEnvironmentChangeEventListener;
import lombok.Data;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @author cuisongxu
 * @date 2023/2/7 11:34
 */
@ConditionalOnClass(DegradeRuleManager.class)
@Configuration
@ConditionalOnProperty(value = "micrometer.sentinel.enabled", havingValue = "true", matchIfMissing = true)
public class SentinelMicrometerAutoConfiguration {

    @Bean
    public SmartInitializingSingleton processSentinelDegradeState(SentinelDegradeState sentinelDegradeState) {
        return () -> {
            sentinelDegradeState.registerDegradeStateChangeObserver();
            sentinelDegradeState.bindTo(MonitorContext.get().getMeterRegistry());
            MetricExtensionProvider.addMetricExtension(new SentinelMetricsExtension());
        };
    }

    @Bean
    public SentinelDegradeState sentinelDegradeState(ApiDegradeStatus test) {
        return new SentinelDegradeState(test);
    }


    @Bean
    public ApiDegradeStatus apiDegradeStatus() {
        return new ApiDegradeStatus();
    }


    @Bean
    public SentinelEnvironmentChangeEventListener sentinelEnvironmentChangeEventListener(SentinelDegradeState sentinelDegradeState) {
        return new SentinelEnvironmentChangeEventListener(sentinelDegradeState);
    }

    @Data
    public class ApiDegradeStatus {
        Map<String, Integer> apiDegradeStatusMap = new HashMap<>();
    }
}
